package com.avocado.bt.parse;

import com.avocado.bt.BTManager;
import com.avocado.bt.IBTContext;
import com.avocado.bt.IBTNode;
import com.avocado.bt.impl.Tree;
import com.avocado.bt.impl.TreeBuilder;
import com.avocado.bt.impl.conatext.ContextBuilder;
import com.avocado.bt.parse.modle.BTTree;
import com.avocado.mock.Player;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: zsh
 * @Date: 2023/10/17 10:00
 */
public class BTParser {

    public final static String resourceFileName = "bt.yml";

    public static void parse() {
        try (InputStream resource = BTTree.class.getClassLoader().getResourceAsStream(resourceFileName)) {
            Yaml yaml = new Yaml(new Constructor(BTTree.class));
            Iterable<Object> its = yaml.loadAll(resource);
            List<BTTree> BTTrees = new ArrayList<>();
            for (Object it : its) {
                BTTrees.add((BTTree) it);
            }
            for (BTTree btTree : BTTrees) {
                Tree tree = build(btTree);
                BTManager.addTree(tree);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static Tree build(BTTree tree) {
        Player player = Player.valueOf();
        IBTContext context = ContextBuilder.build(player);
        TreeBuilder treeBuilder = new TreeBuilder(context);
        build(treeBuilder, tree);
        return treeBuilder.build();
    }

    public static void build(TreeBuilder treeBuilder, BTTree tree) {
        try {
            IBTNode ibtNode = BTManager.newNodeInstance(tree.getType(), tree.getParam());
            treeBuilder.addBehaviour(ibtNode);

            if (tree.getChild() == null) {
                return;
            }

            for (BTTree btTree : tree.getChild()) {
                build(treeBuilder, btTree);
                treeBuilder.back();
            }
        } catch (Exception e) {
            throw new RuntimeException(tree.getType() + ": " + e.getMessage());
        }
    }

}
